﻿using IdentityModel;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using Mojito.Model;
using Mojito.Services;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace Mojito.Controllers
{
    [Route("api/user")]
    public class SysAccountController : ControllerBase
    {
        /// <summary>
        ///  系统账户
        /// </summary>
        public SysAccountService SysAccountService { get; set; }

        /// <summary>
        ///  登入
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("login")]
        [AllowAnonymous]
        public IActionResult Login([FromBody] SignInInput input)
        {
            var user = SysAccountService.Login(input.Credential, input.Password);
            var userid = user.Id.ToString();

            // 登录
            var claimIdentity = GetClaimsIdentity(userid);
            // 制作并返回 Token
            return Success(data: GetToken(claimIdentity));
        }

        /// <summary>
        ///  登出
        /// </summary>
        /// <returns></returns>
        [HttpPost("logout")]
        [AllowAnonymous]
        public IActionResult Logout()
        {
            return Success();
        }

        /// <summary>
        ///  注册
        /// </summary>
        /// <returns></returns>
        [HttpPost("register")]
        [AllowAnonymous]
        public async Task<IActionResult> Register([FromBody] RegisterInput input)
        {
            await SysAccountService.Register(input.Credential, input.Password, input.Phone);
            return Success("注册成功");
        }

        /// <summary>
        ///  我的账号信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("my/info")] 
        public async Task<IActionResult> MyInfo()
        {
            var user = await SysAccountService.Get(CurrentUser.Id);
            var output = new UserInfoOutput
            {
                Id = user.Id,
                Username = user.Username,
                Name = user.Name,
                Email = user.Email,
                Photo = user.Photo,
                TelPhone = user.TelPhone,
            };
            return Success("更新成功", output);
        }

        /// <summary>
        ///  更新我的账号信息
        /// </summary>
        /// <returns></returns>
        [HttpPost("my/info")]
        public IActionResult UpdateMyInfo()
        {
            var output = new UserInfoOutput
            {
                Id = "1",
                Username = "Xlit",
                Name = "xlit",
                Email = "",
                Photo = "photo",
                TelPhone = "15657795562",
            };
            return Success("更新成功", output);
        }

        /// <summary>
        ///  更新我的密码
        /// </summary>
        /// <returns></returns>
        [HttpPost("my/password")]
        public IActionResult ModifyPassword()
        {
            return Success("更新成功");
        }

        /// <summary>
        ///  根据用户名搜索用户
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        [HttpGet("search")]
        public async Task<IActionResult> Search(string username)
        {
            var userList = (await SysAccountService
                .GetByUsername(username))
                .Where(d => d.Id != CurrentUser.Id)
                .Select(d => new
                {
                    d.Id,
                    d.Username
                });
            return Success(data: userList);
        }

        /// <summary>
        ///  制作身份凭证
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        [NonAction]
        protected ClaimsIdentity GetClaimsIdentity(string userid)
        {
            IList<Claim> claimList = new List<Claim>()
            {
                new Claim(JwtClaimTypes.Audience, "api"),
                new Claim(JwtClaimTypes.Id, userid)
            };
            return new ClaimsIdentity(claimList, JwtBearerDefaults.AuthenticationScheme);
        }

        /// <summary>
        ///  加密身份凭证制作 Token
        /// </summary>
        /// <param name="claimIdentity"></param>
        /// <returns></returns>
        [NonAction]
        protected string GetToken(ClaimsIdentity claimIdentity)
        {
            var securityKeyByte = Encoding.ASCII.GetBytes(DefineVar.ISSUER_SIGNING_KEY);
            var authTime = DateTime.UtcNow;
            var expiresAt = authTime.AddDays(30);

            var tokenDescriptor = new SecurityTokenDescriptor()
            {
                Subject = claimIdentity,
                Expires = expiresAt,
                SigningCredentials = new SigningCredentials(
                    new SymmetricSecurityKey(securityKeyByte),
                    SecurityAlgorithms.HmacSha256Signature)
            };

            var tokenHandler = new JwtSecurityTokenHandler();
            var token = tokenHandler.CreateToken(tokenDescriptor);
            var tokenString = tokenHandler.WriteToken(token);
            return tokenString;
        }
    }
}
